home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / gfx / show / vmpeg.lha / src / systems.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-07-06  |  6.2 KB  |  275 lines

  1. /* systems.c, systems-specific routines                                 */
  2.  
  3. /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
  4.  
  5. /*
  6.  * Disclaimer of Warranty
  7.  *
  8.  * These software programs are available to the user without any license fee or
  9.  * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
  10.  * any and all warranties, whether express, implied, or statuary, including any
  11.  * implied warranties or merchantability or of fitness for a particular
  12.  * purpose.  In no event shall the copyright-holder be liable for any
  13.  * incidental, punitive, or consequential damages of any kind whatsoever
  14.  * arising from the use of these programs.
  15.  *
  16.  * This disclaimer of warranty extends to the user of these programs and user's
  17.  * customers, employees, agents, transferees, successors, and assigns.
  18.  *
  19.  * The MPEG Software Simulation Group does not represent or warrant that the
  20.  * programs furnished hereunder are free of infringement of any third-party
  21.  * patents.
  22.  *
  23.  * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
  24.  * are subject to royalty fees to patent holders.  Many of these patents are
  25.  * general enough such that they are unavoidable regardless of implementation
  26.  * design.
  27.  *
  28.  */
  29.  
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32.  
  33. #include "config.h"
  34. #include "global.h"
  35. #include "audio.h"
  36.  
  37. /* initialize buffer, call once before first getbits or showbits */
  38.  
  39. /* parse system layer, ignore everything we don't need */
  40. void Next_Packet()
  41. {
  42.   unsigned int code;
  43.   int l;
  44.  
  45.   for(;;)
  46.   {
  47.     code = Get_Long();
  48.  
  49.     /* remove system layer byte stuffing */
  50.     while ((code & 0xffffff00) != 0x100)
  51.       code = (code<<8) | Get_Byte();
  52.  
  53.     switch(code)
  54.     {
  55.     case PACK_START_CODE: /* pack header */
  56.       /* skip pack header (system_clock_reference and mux_rate) */
  57.       ld->Rdptr += 8;
  58.       break;
  59.  
  60.     case VIDEO_ELEMENTARY_STREAM:   
  61.       code = Get_Word();             /* packet_length */
  62.       ld->Rdmax = ld->Rdptr + code;
  63.  
  64.       code = Get_Byte();
  65.  
  66.       if((code>>6)==0x02)
  67.       {
  68.         ld->Rdptr++;
  69.         code=Get_Byte();  /* parse PES_header_data_length */
  70.         ld->Rdptr+=code;    /* advance pointer by PES_header_data_length */
  71.         printf("MPEG-2 PES packet\n");
  72.         return;
  73.       }
  74.       else if(code==0xff)
  75.       {
  76.         /* parse MPEG-1 packet header */
  77.         while((code=Get_Byte())== 0xFF);
  78.       }
  79.        
  80.       /* stuffing bytes */
  81.       if(code>=0x40)
  82.       {
  83.         if(code>=0x80)
  84.         {
  85.           fprintf(stderr,"Error in packet header\n");
  86.           exit(1);
  87.         }
  88.         /* skip STD_buffer_scale */
  89.         ld->Rdptr++;
  90.         code = Get_Byte();
  91.       }
  92.  
  93.       if(code>=0x30)
  94.       {
  95.         if(code>=0x40)
  96.         {
  97.           fprintf(stderr,"Error in packet header\n");
  98.           exit(1);
  99.         }
  100.         /* skip presentation and decoding time stamps */
  101.         ld->Rdptr += 9;
  102.       }
  103.       else if(code>=0x20)
  104.       {
  105.         /* skip presentation time stamps */
  106.         ld->Rdptr += 4;
  107.       }
  108.       else if(code!=0x0f)
  109.       {
  110.         fprintf(stderr,"Error in packet header\n");
  111.         exit(1);
  112.       }
  113.       return;
  114.  
  115.     case ISO_END_CODE: /* end */
  116.       /* simulate a buffer full of sequence end codes */
  117.       l = 0;
  118.       while (l<STREAMBUFSIZE)
  119.       {
  120.         ld->Rdbfr[l++] = SEQUENCE_END_CODE>>24;
  121.         ld->Rdbfr[l++] = SEQUENCE_END_CODE>>16;
  122.         ld->Rdbfr[l++] = SEQUENCE_END_CODE>>8;
  123.         ld->Rdbfr[l++] = SEQUENCE_END_CODE&0xff;
  124.       }
  125.       ld->Rdptr = ld->Rdbfr;
  126.       ld->Rdmax = ld->Rdbfr + STREAMBUFSIZE;
  127.       return;
  128.  
  129.     case AUDIO_STREAM_0: /* audio part of the stream */
  130.       if(Enable_Sound)
  131.       {
  132.         code = Get_Word();             /* packet_length */
  133.         ld->Rdmax = ld->Rdptr + code;
  134.  
  135.         code = Get_Byte();
  136.  
  137.         if((code>>6)==0x02)
  138.         {
  139.           ld->Rdptr++;
  140.           code=Get_Byte();  /* parse PES_header_data_length */
  141.           ld->Rdptr+=code;    /* advance pointer by PES_header_data_length */
  142.           printf("MPEG-2 PES packet\n");
  143.           return;
  144.         }
  145.         else if(code==0xff)
  146.         {
  147.           /* parse MPEG-1 packet header */
  148.           while((code=Get_Byte())== 0xFF);
  149.         }
  150.        
  151.         /* stuffing bytes */
  152.         if(code>=0x40)
  153.         {
  154.           if(code>=0x80)
  155.           {
  156.             fprintf(stderr,"Error in packet header\n");
  157.             exit(1);
  158.           }
  159.           /* skip STD_buffer_scale */
  160.           ld->Rdptr++;
  161.           code = Get_Byte();
  162.         }
  163.  
  164.         if(code>=0x30)
  165.         {
  166.           if(code>=0x40)
  167.           {
  168.             fprintf(stderr,"Error in packet header\n");
  169.             exit(1);
  170.           }
  171.           /* skip presentation and decoding time stamps */
  172.           ld->Rdptr += 9;
  173.         }
  174.         else if(code>=0x20)
  175.         {
  176.           /* skip presentation time stamps */
  177.           ld->Rdptr += 4;
  178.         }
  179.         else if(code!=0x0f)
  180.         {
  181.           fprintf(stderr,"Error in packet header\n");
  182.           exit(1);
  183.         }
  184.  
  185.         code = ld -> Rdmax - ld -> Rdptr;
  186.  
  187.         /* feed audio-buffer with data */
  188.  
  189.         while((code--)>0) audio_feedbuffer((unsigned char)Get_Byte());
  190.         break;
  191.       }
  192.  
  193.     default:
  194. #if 1 /* skip all */
  195.       code = Get_Word();
  196.       ld->Rdptr += code;
  197. #else
  198.       if(code>=SYSTEM_START_CODE)
  199.       {
  200.         /* skip system headers and non-video packets*/
  201.  
  202.         code = Get_Word();
  203.         ld->Rdptr += code;
  204.       }
  205.       else
  206.       {
  207.         fprintf(stderr,"Unexpected startcode %08x in system layer\n",code);
  208.         exit(1);
  209.       }
  210. #endif
  211.       break;
  212.     }
  213.   }
  214. }
  215.  
  216.  
  217.  
  218. void Flush_Buffer32()
  219. {
  220.   int Incnt;
  221.  
  222.   ld->Bfr = 0;
  223.  
  224.   Incnt = ld->Incnt;
  225.   Incnt -= 32;
  226.  
  227.   if (System_Stream_Flag && (ld->Rdptr >= ld->Rdmax-4))
  228.   {
  229.     while (Incnt <= 24)
  230.     {
  231.       if (ld->Rdptr >= ld->Rdmax)
  232.         Next_Packet();
  233.       ld->Bfr |= Get_Byte() << (24 - Incnt);
  234.       Incnt += 8;
  235.     }
  236.   }
  237.   else
  238.   {
  239.     while (Incnt <= 24)
  240.     {
  241.       if (ld->Rdptr >= ld->Rdbfr+STREAMBUFSIZE)
  242.         Fill_Buffer();
  243.       ld->Bfr |= *ld->Rdptr++ << (24 - Incnt);
  244.       Incnt += 8;
  245.     }
  246.   }
  247.   ld->Incnt = Incnt;
  248.  
  249. #ifdef VERIFY 
  250.   ld->Bitcnt += 32;
  251. #endif /* VERIFY */
  252. }
  253.  
  254.  
  255. unsigned int Get_Bits32()
  256. {
  257.   unsigned int l;
  258.  
  259.   l = Show_Bits(32);
  260.   Flush_Buffer32();
  261.  
  262.   return l;
  263. }
  264.  
  265.  
  266. int Get_Long()
  267. {
  268.   int i;
  269.  
  270.   i = Get_Word();
  271.   return (i<<16) | Get_Word();
  272. }
  273.  
  274.  
  275.